from rest_framework import serializers

from oauth.models import OAuthQQUser
from oauth.utils import decode_sign_openid
from django_redis import get_redis_connection
from users.models import User

class OAuthQQUserSerializer(serializers.Serializer):
    password = serializers.CharField(min_length=8, max_length=8, label="密码")
    mobile = serializers.RegexField(label="手机号验证", regex=r'^1[3-9]\d{9}$')
    sms_code = serializers.CharField(min_length=6, max_length=6, label="短信验证码")
    access_token = serializers.CharField(label="加密openid")

    # 多字段效验
    def validate(self, attrs):
        # 效验openid
        openid = decode_sign_openid(attrs["access_token"])  # 使用解密方法来解密传参进来的access_token
        if not openid:
            raise serializers.ValidationError("openid失效")

        # 效验短信验证码
        sms_code = attrs["sms_code"]  # 取出短信验证码
        mobile = attrs["mobile"]    # 取出手机号
        redis_conn = get_redis_connection("code")  # code库
        redis_sms_code = redis_conn.get("sms_code_%s" % mobile)  # 获取redis的code库里存储的短信验证码
        if not redis_sms_code:
            raise serializers.ValidationError("短信验证码已过期")

        if sms_code != redis_sms_code.decode():
            raise serializers.ValidationError("短信验证码错误")

        # 效验密码
        user = None  # 新用户占位
        try:
            user = User.objects.get(mobile=mobile)
        except User.DoesNotExist:
            pass
        else:
            if not user.check_password(attrs["password"]):
                raise serializers.ValidationError("密码错误")
        attrs["openid"] = openid
        attrs["user"] = user
        return attrs

    # 重写create方法,执行入库
    def create(self, validated_data):
        # 获取数据
        openid = validated_data["openid"]  # 获得上面多字段效验时添加的openid属性信息
        user = validated_data["user"]
        # 判断是否存在user
        if not user:  # 如果user为None 则创建一个user
            user = User.objects.create_user(
                username=validated_data["mobile"],
                password=validated_data["password"],
                mobile=validated_data["mobile"]
            )

        # 创建OAuthQQUser对象, 绑定美多用户
        OAuthQQUser.objects.create(openid=openid, user=user)

        # 返回响应
        return user